<?php
/**
 * 域名防封检测
 */
namespace App\Jobs\Timer;

use Hhxsv5\LaravelS\Swoole\Timer\CronJob;
use App\Services\CdnService;
use App\Services\SendSmsService;
use App\Models\Domain;
use App\Models\CdnDomain;
use Carbon\Carbon;

class DomainCheck extends  CronJob
{
    protected $base = "http://vip.xxweixin.com/weixin/wx_domain.php?user=jc1689506244&key=524eca663742b44cbdeea48592934bcb&domain=";
    
    // 每隔 1000ms 执行一次任务
    public function interval()
    {
        return 4000;   // 定时器间隔，单位为 ms
    }

    // 是否在设置之后立即触发 run 方法执行
    public function isImmediate()
    {
        // 是否立即执行第一次，false则等待间隔时间后执行第一次
        return false;
    }
    
    // 该方法可类比为 Swoole 定时器中的回调方法
    public function run()
    {
        $cdn_service = new CdnService();
        //入口检测
        $enter_domain = cache()->remember('enter_domain',1800,function(){
            return Domain::show()->enter()->value('domain');
        });
        if($enter_domain){
            $url = $this->base.$enter_domain;
            \Log::channel('check_domain')->info(__METHOD__, ['start', "检测入口：{$enter_domain}", microtime(true)]);
            $content = curlRequest($url);
            $res = $this->getResult($content);
            //域名被封
            if($res['state'] && $res['code'] == -1){
                //发短信
                $this->createSms('入口红',$enter_domain);
                //数据库修改状态
                Domain::where('state','<>',-1)->where('domain',$enter_domain)->update(['state'=>-1]);
                //清缓存
                cache()->forget('enter_domain');
            }

        }
        //落地检测
        $born_domain = cache()->remember('born_domain',1800,function(){
            return Domain::show()->born()->orderBy('sort')->value('domain');
        });
        if($born_domain){
            $url = $this->base.$born_domain;
            sleep(2);//检测频率2秒
            \Log::channel('check_domain')->info(__METHOD__, ['start', "检测落地：{$born_domain}", microtime(true)]);
            $content = curlRequest($url);
            $res = $this->getResult($content);
            //域名被封
            if($res['state'] && $res['code'] == -1){
                //发短信
                $this->createSms('落地红',$born_domain);
                //数据库修改状态
                Domain::where('state','<>',-1)->where('domain',$born_domain)->update(['state'=>-1]);
                //清缓存
                cache()->forget('born_domain');
            }
        }
        //cdn 检测
        //图片cdn
        $img_cdns = $cdn_service->getImgCdn();
       
        if($img_cdns['state']!='success' || ($img_cdns['img_cdn1']=='' && $img_cdns['img_cdn2']=='')){
            //清空缓存
            cache()->forget('img_cdn1');
            cache()->forget('img_cdn2');
            cache()->forget('img_cdn_count');
        }
        else{
            if($img_cdns['img_cdn1']){
                $url = $this->base.$img_cdns['img_cdn1']['domain'];
                sleep(2);//检测频率2秒
                \Log::channel('check_domain')->info(__METHOD__, ['start', "检测图片CDN1：{$img_cdns['img_cdn1']['domain']}", microtime(true)]);
                $content = curlRequest($url);
                $res = $this->getResult($content);
                //域名被封
                if($res['state'] && $res['code'] == -1){
                    //发短信
                    $this->createSms('图CDN红',$img_cdns['img_cdn1']['domain']);
                    //数据库修改状态
                    CdnDomain::where('state','<>',-1)->where('domain',$img_cdns['img_cdn1']['domain'])->update(['state'=>-1]);
                    //清缓存
                    cache()->forget('img_cdn1');
                    cache()->forget('img_cdn_count');
                }
            }
            if($img_cdns['img_cdn2'] && $img_cdns['img_cdn2'] != $img_cdns['img_cdn1']){
                $url = $this->base.$img_cdns['img_cdn2']['domain'];
                sleep(2);//检测频率2秒
                \Log::channel('check_domain')->info(__METHOD__, ['start', "检测图片CDN2：{$img_cdns['img_cdn2']['domain']}", microtime(true)]);
                $content = curlRequest($url);
                $res = $this->getResult($content);
                //域名被封
                if($res['state'] && $res['code'] == -1){
                    //发短信
                    $this->createSms('图CDN红',$img_cdns['img_cdn2']['domain']);
                    //数据库修改状态
                    CdnDomain::where('state','<>',-1)->where('domain',$img_cdns['img_cdn2']['domain'])->update(['state'=>-1]);
                    //清缓存
                    cache()->forget('img_cdn2');
                    cache()->forget('img_cdn_count');
                }
            }
        }
        //视频cdn
        $video_cdns = $cdn_service->getVideoCdn();
        if($video_cdns['state']!='success' || ($video_cdns['video_cdn1']=='' && $video_cdns['video_cdn2']=='')){
            //清空缓存
            cache()->forget('video_cdn1');
            cache()->forget('video_cdn2');
            cache()->forget('video_cdn_count');
        }
        else{
            if($video_cdns['video_cdn1']){
                $url = $this->base.$video_cdns['video_cdn1']['domain'];
                sleep(2);//检测频率2秒
                \Log::channel('check_domain')->info(__METHOD__, ['start', "检测视频CDN1：{$video_cdns['video_cdn1']['domain']}", microtime(true)]);
                $content = curlRequest($url);
                $res = $this->getResult($content);
                //域名被封
                if($res['state'] && $res['code'] == -1){
                    //发短信
                    $this->createSms('视频CDN红',$video_cdns['video_cdn1']['domain']);
                    //数据库修改状态
                    CdnDomain::where('state','<>',-1)->where('domain',$video_cdns['video_cdn1']['domain'])->update(['state'=>-1]);
                    //清缓存
                    cache()->forget('video_cdn1');
                    cache()->forget('video_cdn_count');
                }
            }
            if($video_cdns['video_cdn2'] && $video_cdns['video_cdn2'] != $video_cdns['video_cdn1']){
                $url = $this->base.$video_cdns['video_cdn2']['domain'];
                sleep(2);//检测频率2秒
                \Log::channel('check_domain')->info(__METHOD__, ['start', "检测视频CDN2：{$video_cdns['video_cdn2']['domain']}", microtime(true)]);
                $content = curlRequest($url);
                $res = $this->getResult($content);
                //域名被封
                if($res['state'] && $res['code'] == -1){
                    //发短信
                    $this->createSms('视频CDN红',$video_cdns['video_cdn2']['domain']);
                    //数据库修改状态
                    CdnDomain::where('state','<>',-1)->where('domain',$video_cdns['video_cdn2']['domain'])->update(['state'=>-1]);
                    //清缓存
                    cache()->forget('video_cdn2');
                    cache()->forget('video_cdn_count');
                }
            }
        }
         //图片服务器域名
        $img_domain = cache()->rememberForever('img_domain',  function () {
            //落地有可能没有了，所以加锁防止没有时缓存穿透
            return cache()->lock('img_domain')->get(function () {
                // 获取无限期锁并自动释放...
                return CdnDomain::show()->where('type',3)->value('domain');
            });
        });
        if(!empty($img_domain)){
            $url = $this->base.$img_domain;
            sleep(2);//检测频率2秒
            \Log::channel('check_domain')->info(__METHOD__, ['start', "图片直连服务器：{$img_domain}", microtime(true)]);
            $content = curlRequest($url);
            $res = $this->getResult($content);
            //域名被封
            if($res['state'] && $res['code'] == -1){
                //发短信
                $this->createSms('图片服务器',$img_domain);
                //数据库修改状态
                CdnDomain::where('state','<>',-1)->where('domain',$img_domain)->update(['state'=>-1]);
                //清缓存
                cache()->forget('img_domain');
            }
        }
    }


    /**
     * 解析结果
     */
    protected function getResult($content){
        $res['state'] = false;
        $res['code'] = 0;
        $res['msg'] = '';
        if(strrpos($content,"参数错误")>0){
            $res['msg'] = "参数错误";
            \Log::channel('check_domain_err')->error(__METHOD__, ['start', '域名检测参数错误', microtime(true)]);
            return $res;
        }
        else if(strrpos($content,"频率")>0){
            \Log::channel('check_domain_err')->error(__METHOD__, ['start', '域名检测频率过快', microtime(true)]);
            $res['msg'] = "频率过快";
            return $res;
        }
        $res['state'] = true;
        $data = json_decode($content,true);
        if($data['status']==2){
            $res['code'] = -1;
            $res['msg'] = '域名被封';
        }else if($data['status']==0){
            $res['msg'] = '域名正常';
        }else if($data['status']==3){
            $res['code'] = -2;
            \Log::channel('check_domain_err')->error(__METHOD__, ['start', '域名检测查询失败', microtime(true)]);
            $res['msg'] = '查询失败';
        }else if($data['status']==-1){
            \Log::channel('check_domain')->error(__METHOD__, ['start', $data, microtime(true)]);
            $res['msg'] = $data['errmsg'];
        }
        return $res;
    }


    /**
     * 创建短信
     */
    protected function createSms($type,$domain){
        $phone = config('visit.domain_notice_phone');
        if($phone){
            $time = Carbon::now();
            $content = "鱼塘（{$type}）鱼米（{$domain}）出现问题，时间：（{$time}）。请及时处理。【鱼塘环境监测】";
            $sms_service = new SendSmsService();
            $sms_service->send($phone,$content);
        }
    }
}
